﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.IO;
using System.Text.RegularExpressions;

namespace BigPixels
{
    public static class BigPixelStorage
    {
        public static List<PixelValue> LoadPalette(string fileName)
        {
			List<PixelValue> palette = new List<PixelValue>();

			try
			{
				palette = XmlSerializer<List<PixelValue>>.Load(fileName);
			}
			catch (FileNotFoundException)
			{
				string[] colours = { "000000" , "FFFFFF", "010018", "010018", "69130B", "39246D", "AA3D4D", "2E4FDA", "D9845A",
										"2A9460", "AAAAAA", "BBBBBB", "CCCCCC", "E2D7E0", "BFEA63", "75EFE6" };

				foreach (string colour in colours)
				{
					palette.Add(new PixelValue(colour));
				}
			}

			return palette;
        }

        public static void SavePalette(string fileName, List<PixelValue> colours)
        {
            XmlSerializer<List<PixelValue>>.Save(fileName, colours);
        }

        public static List<PixelValue> LoadPaletteFromImage(string fileName)
        {
            var imageColours = new List<PixelValue>();

            if (File.Exists(fileName))
            {
                var uniqueColours = new Dictionary<Color, int>();
                var allColours = new Dictionary<Color, int>();

                using (Bitmap bitmap = new Bitmap(Bitmap.FromFile(fileName)))
                {
                    for (int i = 0; i < bitmap.Width; ++i)
                    {
                        for (int j = 0; j < bitmap.Height; ++j)
                        {
                            Color candidate = bitmap.GetPixel(i, j);

                            if (!allColours.ContainsKey(candidate))
                            {
                                allColours.Add(candidate, 1);

                                if (uniqueColours.ContainsKey(candidate))
                                    uniqueColours[candidate]++;
                                else
                                {
                                    bool isClose = false;

                                    foreach (var color in uniqueColours.Keys)
                                    {
                                        if (color.IsCloseTo(candidate))
                                        {
                                            isClose = true;
                                            break;
                                        }
                                    }

                                    if (!isClose)
                                    {
                                        uniqueColours.Add(candidate, 1);
                                    }
                                }
                            }
                        }
                    }
                }

                var keyValueList = new List<KeyValuePair<Color, int>>(uniqueColours);

                keyValueList.Sort(delegate(KeyValuePair<Color, int> firstPair, KeyValuePair<Color, int> nextPair)
                                            {
                                                return firstPair.Key.CompareTo(nextPair.Key);
                                            });

                foreach (var pair in keyValueList)
                {
                    imageColours.Add(new PixelValue(pair.Key));
                }

            }

            return imageColours;
        }

        public static List<Cell> LoadCells(string fileName)
        {
            return XmlSerializer<List<Cell>>.Load(fileName);
        }

        public static void SaveCells(string fileName, List<Cell> cells)
        {
            XmlSerializer<List<Cell>>.Save(fileName, cells);
        }
    }
}
